//
// Created .second Jisam on 2024/8/20 7:49.
// Solution of  P1429 平面最近点对（加强版）
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <vector>

using namespace std;

#define endl "\n"
#define PSI pair<string,int>
#define PII pair<int,int>
#define PDI pair<double,int>
#define PDD pair<double,double>
#define VVI vector<vector<int>>
#define VI vector<int>
#define VS vector<string>

#define PQLI priority_queue<int, vector<int>, less<int>>
#define PQGI priority_queue<int, vector<int>, greater<int>>
#define code_by_jisam ios::sync_with_stdio(false),cin.tie(nullptr)
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
int dx[] = {-1, 1, 0, 0, 1, 1, -1, -1,};
int second[] = {0, 0, -1, 1, 1, -1, -1, 1,};
// 定义一个常量INF，用于表示无穷大的值
constexpr i64 INF = 5e18;
// 临时数组tmp，用于归并排序过程中的临时存储
vector<PII> tmp(2000000),a(2000000);
// 数组b，用于在归并排序过程中存储满足条件的点的索引
VI b(2000000);

// 计算一个数的平方
long long sqr(int x){return (long long)x*x;}

// 计算两点之间的距离（其实这里计算的是距离的平方）
long long dis(int l,int r ){return sqr(a[l].first-a[r].first)+sqr(a[l].second-a[r].second);}



// 归并排序函数，用于对数组a的[l,r]区间进行归并排序
void merge(int l,int r )
{
    int mid=(l+r)>>1,i=l,j=mid+1;//初始化归并所需的指针
    // 遍历[l,r]区间，根据点的y坐标进行归并排序
    for(int k=l;k<=r;k++)
    {
        if(i<=mid&&(j>r||a[i].second<a[j].second))tmp[k]=a[i++];
        else tmp[k]=a[j++];
    }
    // 将排序后的结果复制回原数组a
    for(int i=l;i<=r;i++)a[i]=tmp[i];
}

// 解决问题的核心递归函数，用于计算数组a的[l,r]区间内两点的最小距离的平方
i64 solve(int l,int r ){
    // 当区间内只有一个点时，返回无穷大
    if( l >= r) return INF;

    // 当区间内只有两个点时，直接计算并返回两点间的距离的平方
    if( l + 1 == r){
        if(a[l].second > a[r].second) swap(a[l],a[r]);
        return dis(l,r);
    }

    // 分治，计算中点位置
    int mid=(l+r)>>1;

    // 记录中点的x坐标，用于后续判断点是否接近中点
    int t=a[mid].first;

    // 初始化计数器cnt为0，用于记录满足条件的点的数量
    int cnt=0;

    // 递归计算左半部分和右半部分的最小距离的平方，并取两者的较小值
    i64 d=min(solve(l,mid),solve(mid+1,r));

    // 归并排序左半部分和右半部分
    merge(l,r);

    // 遍历[l,r]区间内的所有点，找出距离中点x坐标距离小于d的点
    for(int i=l;i<=r;i++)
        if(sqr(a[i].first-t)<d)
            b[++cnt]=i;//将满足条件的点的索引存储到数组b中

    // 遍历数组b中存储的点，计算它们之间的距离的平方，并更新最小值
    for(int i=1;i<=cnt;i++)
        for(int j=i+1;j<=cnt&&sqr(a[b[j]].second-a[b[i]].second)<d;j++)
            d=min(d,dis(b[j],b[i]));

    // 返回[l,r]区间内两点的最小距离的平方
    return d;
}

// 解决问题的入口函数
void solution() {
    // 读入点的数量
    int n;
    cin >> n;
    // 初始化点的坐标数组

    // 读入每个点的坐标
    for(int i = 1 ; i <= n ; i ++){
        cin >> a[i].first >> a[i].second;
    }
    // 对点按照x坐标进行排序，如果x坐标相同，则按照y坐标排序
    sort(a.begin() + 1,a.begin() + 1 + n,[&](PII a , PII b){
        return a.first == b.first  ? a.second < b.second : a.first < b.first;
    });

    // 输出最小距离（开方后的结果）
    cout << fixed << setprecision(4) << sqrt(solve(1,n));
}


int main() {
    code_by_jisam;
    int T = 1;
//    cin >> T;
    while (T--) {
        solution();
    }
    return 0;
}